import java.util.*;

public class 可排序数组比较<T extends Comparable> {
    private T[] array1;
    private T[] array2;

    public 可排序数组比较(T[] a1, T[] a2) {
        Arrays.sort(a1);
        Arrays.sort(a2);
        this.array1 = a1;
        this.array2 = a2;
    }

    public 可排序数组比较(T[] a1, T[] a2, Comparator<T> comparator) {
        if (a1 == null || a2 == null) {
            throw new IllegalArgumentException("param must not be null");
        }
        if (comparator != null) {
            Arrays.sort(a1, comparator);
            Arrays.sort(a2, comparator);
        } else {
            Arrays.sort(a1);
            Arrays.sort(a2);
        }
        this.array1 = a1;
        this.array2 = a2;
    }

    public List<T> diff() {
        List<T> list = new ArrayList<>(array1.length);
        int ol = array1.length;
        int tl = array2.length;
        int x = 0, y = 0;
        for (; x < ol && y < tl; ) {
            if (array1[x].equals(array2[y])) {
                x++;
                y++;
                continue;
            }
            if (array1[x].compareTo(array2[y]) > 0) {
                list.add(array2[y++]);
            } else {
                list.add(array1[x++]);
            }
        }
        if (x < ol) {
            for (int i = x; i < ol; i++) {
                list.add(array1[i]);
            }
        } else if (y < tl) {
            for (int i = y; i < tl; i++) {
                list.add(array2[i]);
            }
        }
        return list;
    }

    public List<T> firstMore() {
        List<T> list = new ArrayList<>(array1.length);
        int ol = array1.length;
        int tl = array2.length;
        int x = 0, y = 0;
        for (; x < ol && y < tl; ) {
            if (array1[x].equals(array2[y])) {
                x++;
                y++;
                continue;
            }
            if (array1[x].compareTo(array2[y]) < 0) {
                list.add(array1[x++]);
                continue;
            }
            y++;
        }
        if (x < ol) {
            for (int i = x; i < ol; i++) {
                list.add(array1[i]);
            }
        }
        return list;
    }

    public List<T> secondMore() {
        List<T> list = new ArrayList<>(array1.length);
        int ol = array1.length;
        int tl = array2.length;
        int x = 0, y = 0;
        for (; x < ol && y < tl; ) {
            if (array1[x].equals(array2[y])) {
                x++;
                y++;
                continue;
            }
            if (array1[x].compareTo(array2[y]) > 0) {
                list.add(array2[y++]);
                continue;
            }
            x++;
        }
        if (y < tl) {
            for (int i = y; i < tl; i++) {
                list.add(array2[i]);
            }
        }
        return list;
    }

    public List<T> same() {
        List<T> list = new ArrayList<>(array1.length);
        int ol = array1.length;
        int tl = array2.length;
        int x = 0, y = 0;
        for (; x < ol && y < tl; ) {
            if (array1[x].equals(array2[y])) {
                list.add(array2[y]);
                x++;
                y++;
                continue;
            }
            if (array1[x].compareTo(array2[y]) > 0) {
                y++;
                continue;
            }
            x++;
        }
        return list;
    }

    public List<T> union(){
        List<T> list = new ArrayList<>(array1.length);
        int ol = array1.length;
        int tl = array2.length;
        int x = 0, y = 0;
        for (; x < ol && y < tl; ) {
            if (array1[x].equals(array2[y])) {
                list.add(array2[y]);
                x++;
                y++;
                continue;
            }
            if (array1[x].compareTo(array2[y]) > 0) {
                list.add(array2[y++]);
            } else {
                list.add(array1[x++]);
            }
        }
        if (x < ol) {
            for (int i = x; i < ol; i++) {
                list.add(array1[i]);
            }
        } else if (y < tl) {
            for (int i = y; i < tl; i++) {
                list.add(array2[i]);
            }
        }
        return list;
    }

    public static void main(String[] args) {
        可排序数组比较<Integer> arr = new 可排序数组比较<>(new Integer[]{1, 7, 3, 4, 5, 323, 23, 33, 43, 12}, new Integer[]{32, 31, 33, 43, 4, 5, 6, 7, 8});
        System.out.println(arr.diff());
        System.out.println(arr.same());
        System.out.println(arr.union());
        System.out.println(arr.firstMore());
        System.out.println(arr.secondMore());
    }
}
